package easy.trace.agent.support;


import com.alibaba.dubbo.rpc.RpcContext;
import easy.trace.BinaryAnnotation;
import easy.trace.Endpoint;
import easy.trace.Span;
import easy.trace.agent.Tracer;
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class BaseInterceptor {
    private static Logger logger = LoggerFactory.getLogger(BaseInterceptor.class);
    private static Tracer tracer = null;
    private Endpoint endpoint;

    public BaseInterceptor() {
        try {
            this.endpoint = new Endpoint(InetAddress.getLocalHost().getHostAddress(), Integer.valueOf(0));
        } catch (UnknownHostException var2) {
            this.endpoint = new Endpoint("127.0.0.1", Integer.valueOf(0));
        }

    }

    /*public BaseInterceptor(Tracer tracer) {
        try {
            this.tracer = tracer;
            this.endpoint = new Endpoint(InetAddress.getLocalHost().getHostAddress(), Integer.valueOf(0));
        } catch (UnknownHostException var3) {
            this.endpoint = new Endpoint("127.0.0.1", Integer.valueOf(0));
        }

    }*/

    public Span newSpan(String serviceId, String methodName) {
        if (tracer == null) {
            tracer = Tracer.getTracer();
        }

        Span span = null;

        try {
            Span spanOld = tracer.getParentSpan();
            if (spanOld == null) {
                span = tracer.newSpan(serviceId, methodName);
            } else {
                span = tracer.genSpan(spanOld.getTraceId(), spanOld.getId(), tracer.genSpanId(), methodName, serviceId);
            }

            this.setAttachment(span);
            this.invokerBefore(span);
        } catch (Exception var5) {
            logger.error(var5.getLocalizedMessage());
        }

        return span;
    }

    public void invokerAfter(Span span) {
        if (tracer == null) {
            tracer = Tracer.getTracer();
        }

        if (span != null) {
            tracer.serverSendRecord(span, this.endpoint, System.currentTimeMillis());
            tracer.removeParentSpan();
            tracer.clientReceiveRecord(span, this.endpoint, System.currentTimeMillis());
        }

    }

    private void setAttachment(Span span) {
        RpcContext invocation = RpcContext.getContext();
        invocation.setAttachment("parentId", span.getParentId() != null ? String.valueOf(span.getParentId()) : null);
        invocation.setAttachment("spanId", span.getId() != null ? String.valueOf(span.getId()) : null);
        invocation.setAttachment("traceId", span.getTraceId() != null ? String.valueOf(span.getTraceId()) : null);
    }

    private void invokerBefore(Span span) {
        tracer.clientSendRecord(span, this.endpoint, System.currentTimeMillis());
        tracer.serverReceiveRecord(span, this.endpoint, System.currentTimeMillis());
        tracer.setParentSpan(span);
    }

    public void catchException(Throwable e) {
        BinaryAnnotation exAnnotation = new BinaryAnnotation();
        exAnnotation.setKey("dubbo.exception");
        exAnnotation.setValue(e.getMessage());
        exAnnotation.setType("ex");
        exAnnotation.setHost(this.endpoint);
        tracer.addBinaryAnntation(exAnnotation);
    }

    public Tracer getTracer() {
        return tracer;
    }

    public void setTracer(Tracer tracer) {
        tracer = tracer;
    }
}
